package com.zhangxin.aiInterview.manager.work_flow.exam_analyze;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.zhangxin.aiInterview.common.ErrorCode;
import com.zhangxin.aiInterview.exception.BusinessException;

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * 笔试结果分析
 */
public class ExamAnalyze {
    public static void main(String[] args) throws Exception {
        System.out.println(analyzeExam(1L, 1L));
    }

    /**
     * 分析笔试结果
     * 
     * @param userId
     * @param examId
     * @return
     * @throws Exception
     */
    public static String analyzeExam(Long userId, Long examId) throws Exception {
        URL url = new URL("https://api.dify.ai/v1/workflows/run");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        // 必须设置的请求头
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "Bearer app-eF7ZxHnxPbhsy8iQIiheCHfS");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Accept", "text/event-stream");

        // 关键连接配置
        conn.setDoOutput(true);
        conn.setChunkedStreamingMode(0); // 启用分块传输
        conn.setReadTimeout(0); // 禁用读取超时

        // 发送请求体
        // todo 后期将数据库修改为线上数据库，因为这个操作是查询的线上数据库中的数据，线上数据库并没有本地数据库的这些数据
        String body = String.format(
                "{\"inputs\": {\"userId\": \"%s\", \"examId\": \"%s\"}, \"response_mode\": \"%s\", \"user\": \"%s\"}",
                userId, examId, "streaming", "1916016714226561026");
        System.out.println("body: " + body);
        try (OutputStream os = conn.getOutputStream()) {
            os.write(body.getBytes(StandardCharsets.UTF_8));
        }

        // 处理流式响应
        String result = "";
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(conn.getInputStream()))) {

            String line;
            while ((line = reader.readLine()) != null) {
                // 跳过心跳包
                if ("event: ping".equals(line.trim())) {
                    continue;
                }

                // 只获取最后一部分的数据
                JSONObject jsonObject = extractOutputs(line);
                if (ObjUtil.isEmpty(jsonObject))
                    continue;
                assert jsonObject != null;
                result = jsonObject.toString();
            }
        }
        return result;
    }

    /**
     * 从给定 JSON 字符串中提取 out3.wrong_questions 数组中的所有 questionTitle 字段
     * 并将其存储到一个 Set<String> 集合中，自动去重
     *
     * @param jsonString 输入的 JSON 字符串
     * @return 包含所有题目标题的字符串集合
     */
    public static List<String> extractQuestionTitlesFromOut3(String jsonString) {
        List<String> questionTitles = new ArrayList<>();

        try {
            // 使用 Hutool JSONUtil 解析字符串为 JSONObject
            JSONObject root = JSONUtil.parseObj(jsonString);

            // 获取 out3 对象
            JSONObject out3 = root.getJSONObject("out3");

            // 获取 wrong_questions 数组
            JSONArray wrongQuestions = out3.getJSONArray("wrong_questions");

            // 遍历数组中的每个 JSONObject，提取 questionTitle 字段
            for (int i = 0; i < wrongQuestions.size(); i++) {
                JSONObject question = wrongQuestions.getJSONObject(i);
                if (question.containsKey("questionTitle")) {
                    String title = question.getStr("questionTitle", "").trim();
                    if (!title.isEmpty()) {
                        questionTitles.add(title);
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("解析 JSON 时发生错误: " + e.getMessage());
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "解析 JSON 时发生错误: " + e.getMessage());
        }
        return questionTitles;
    }

    /**
     * 提取 workflow_finished 事件中的 outputs 数据
     * 
     * @param sseEvent 原始事件字符串（如 "data: {...}"）
     * @return 成功返回 JSONObject 格式的 outputs，失败返回 null
     */
    public static JSONObject extractOutputs(String sseEvent) {
        // 1. 校验并去除 "data: " 前缀
        if (!sseEvent.startsWith("data: ")) {
            return null;
        }
        String jsonStr = sseEvent.substring(6).trim();

        // 2. 解析为 JSONObject
        JSONObject event = JSONUtil.parseObj(jsonStr);
        if (event == null) {
            return null;
        }

        // 3. 校验事件类型
        if (!"workflow_finished".equals(event.getStr("event"))) {
            return null;
        }

        // 4. 提取 outputs
        JSONObject data = event.getJSONObject("data");
        if (data == null) {
            return null;
        }
        return data.getJSONObject("outputs");
    }
}